#include "stdafx.h"

#include <string.h>

#include "omdmsg.h"
#include "ptcomd.h"
#include "uart.h"

static CHAR m_MsgBuf[PTCOMD_MAX_MSG_LEN * 2];
static INT m_iHead, m_iTail;

static HANDLE m_hCom;

static BOOL OmdMsgFindValidMsgHeader(VOID);
static BOOL OmdMsgFindValidMsgBody(UCHAR *pMsg, INT *pMsgLen);
static VOID OmdMsgAdjustMsgBuf(VOID);

BOOL OmdMsgInit(VOID)
{
	m_hCom = UartOpen(OMD_MSG_DEFAULT_COM_NAME, OMD_MSG_DEFAULT_COM_BAUDRATE);
	if ((INT)m_hCom < 0)
	{
		return (FALSE);
	}

	memset(m_MsgBuf, 0, sizeof(m_MsgBuf));
	m_iHead = 0;
	m_iTail = 0;

	return (TRUE);
}

VOID OmdMsgUninit(VOID)
{
	UartClose(m_hCom);
}

static BOOL OmdMsgFindValidMsgHeader(VOID)
{
	CHAR cMsgBuf[2];
	INT i, iSearchLen;

	cMsgBuf[0] = PTCOMD_MAGIC_NUM_1;
	cMsgBuf[1] = PTCOMD_MAGIC_NUM_2;
	iSearchLen = m_iTail - sizeof(cMsgBuf);

	for (i = m_iHead; i < iSearchLen; i++)
	{
		if (!memcmp((void *)&m_MsgBuf[i], (void *)cMsgBuf, sizeof(cMsgBuf)))
		{
			m_iHead = i;
			return (TRUE);
		}
	}

	m_iHead = m_iTail = 0;

	return (FALSE);
}

static BOOL OmdMsgFindValidMsgBody(UCHAR *pMsg, INT *pMsgLen)
{
	if (NULL == pMsg || NULL == pMsgLen)
	{
		exit(1);
	}

	if ((INT)(sizeof(S_PTCOMD_OIL_MIST_STATUS) + m_iHead) <= m_iTail)
	{
		memcpy((void *)pMsg, (void *)&m_MsgBuf[m_iHead],
		  sizeof(S_PTCOMD_OIL_MIST_STATUS));
		m_iHead += sizeof(S_PTCOMD_OIL_MIST_STATUS);
		*pMsgLen = sizeof(S_PTCOMD_OIL_MIST_STATUS);
		return (TRUE);
	}

	return (FALSE);
}

static VOID OmdMsgAdjustMsgBuf(VOID)
{
	CHAR msgBuf[sizeof(m_MsgBuf)];

	memset(msgBuf, 0, sizeof(msgBuf));

	memcpy(msgBuf, &m_MsgBuf[m_iHead], m_iTail - m_iHead);
	memcpy(m_MsgBuf, msgBuf, m_iTail - m_iHead);

	m_iTail -= m_iHead;
	m_iHead = 0;
}

BOOL OmdMsgRecvOneMsg(UCHAR *pMsg, INT *pMsgLen)
{
	BOOL bRet;
	INT iRcvLen;

	if (NULL == pMsg || NULL == pMsgLen)
	{
		exit(1);
	}

	bRet = UartRead(m_hCom, &m_MsgBuf[m_iTail], (INT)(sizeof(m_MsgBuf) - m_iTail),
	  &iRcvLen);
	if (TRUE != bRet)
	{
		return (bRet);
	}

	m_iTail += iRcvLen;

	bRet = OmdMsgFindValidMsgHeader();
	if (TRUE == bRet)
	{
		bRet = OmdMsgFindValidMsgBody(pMsg, pMsgLen);
	}

	OmdMsgAdjustMsgBuf();

	return (bRet);
}

BOOL OmdMsgSendOneMsg(UCHAR *pMsg, INT iMsgLen)
{
	BOOL bRet;
	INT iSendLen;
	UCHAR *pMsgBuf;

	pMsgBuf = pMsg;

	bRet = UartWrite(m_hCom, (CHAR *)pMsgBuf, iMsgLen, &iSendLen);
	if (TRUE != bRet)
	{
		return (FALSE);
	}

	pMsgBuf += iSendLen;
	iMsgLen -= iSendLen;

	while (iMsgLen > 0)
	{
		bRet = UartWrite(m_hCom, (CHAR *)pMsgBuf, iMsgLen, &iSendLen);
		if (TRUE != bRet)
		{
			continue;
		}

		pMsgBuf += iSendLen;
		iMsgLen -= iSendLen;
	}

	return (TRUE);
}
